<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<!-- 
	Copyright (C) 2007, 2008, 2009, 2010, 2011. PARP Research Group.
	<http://perception.inf.um.es>
	University of Murcia, Spain.

	This file is part of the QVision library.

	QVision is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, version 3 of the License.

	QVision is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with QVision. If not, see <http://www.gnu.org/licenses/>.
-->

<html><head><meta http-equiv="content-Type" content="text/html;charset=UTF-8">
<title>QVision: Qt&#39;s Image, Video and Computer Vision Library</title>
<meta name="title" content="QVision" />
<meta name="dc.title" content="QVision" />
<meta name="url" content="http://perception.inf.um.es/QVision" />
<meta name="author" content="PARP Research Group - http://perception.inf.um.es" />
<meta name="revisit-after" content="30 DAYS"/>
<meta name="robots" content="index,follow"/>
<meta name="classification" content="*">
<meta name="rating" content="Safe For Kids">
<meta name="distribution" content="GLOBAL"/>
<meta name="description" content="Qt's Image, Video and Computer Vision Library"/>
<meta name="page-topic" content="Computer Vision research and prototype programming"/>
<meta name="geo.country" content="ES" />

<!--
Keywords:
By license:		open source, gnu, lgpl, gpl, free
By theme:		computer vision, image processing, robotics, programming, source, development
By usage:		library, toolkit, framework, prototype, application
By programming specs:	object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping
Interoperability with:	Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack
Functionallity:		image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface
Main data-types:	matrix, vector, tensor, quaternion, image, polyline
Video sources:		webcam, camera, stream
Devices:		embedded, desktop computer, laptop, mini-laptop
Authors:		PARP research group. University of Murcia, Spain.
-->

<meta name="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="keywords" content="augmented reality, sfm, structure from motion, open source, gnu, lgpl, gpl, free, computer vision, image processing, robotics, programming, source, development, library, toolkit, framework, prototype, application, object oriented, c++, block programming, reusability, gui, graphical, parallel computing, high performance, GPU, prototyping, Qt, GSL, GNU Scientific library, OpenCV, CGAL, QWT, CUDA, mplayer, IPP, Intel Image Performance Primitives, blas, lapack, image features, matrix algebra, projective geometry, mser, function minimization, function optimization, canny operator, harris operator, corner detection, performance evaluation, cpu usage, graphical interface, matrix, vector, tensor, quaternion, image, polyline, webcam, camera, stream, embedded, desktop computer, laptop, mini-laptop, University of Murcia, Spain, PARP research group, vision por computador"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="title" content="QVision"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="tabs.css" rel="stylesheet" type="text/css" />
<link rel="shortcut icon" href="favicon.ico" />
</head><body>

<table width="100%"><tr>
	<td><a href="http://perception.inf.um.es/"><img src="parp.png" border="0" /> <big>PARP Research Group</big></a></td>
	<td align="right"><a href="http://www.um.es/"><big>Universidad de Murcia</big> <img src="um.png" border="0" /></a></td>
</tr></table>

<hr /><br />

<table width="95%" align="center"><tr><td>

<!-- Generated by Doxygen 1.6.3 -->
<script type="text/javascript"><!--
var searchBox = new SearchBox("searchBox", "search",false,'Search');
--></script>
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="index.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li class="current"><a href="files.html"><span>Files</span></a></li>
      <li>
        <div id="MSearchBox" class="MSearchBoxInactive">
          <form id="FSearchBox" action="search.php" method="get">
            <img id="MSearchSelect" src="search/search.png" alt=""/>
            <input type="text" id="MSearchField" name="query" value="Search" size="20" accesskey="S" 
                   onfocus="searchBox.OnSearchFieldFocus(true)" 
                   onblur="searchBox.OnSearchFieldFocus(false)"/>
          </form>
        </div>
      </li>
    </ul>
  </div>
  <div class="tabs">
    <ul>
      <li><a href="files.html"><span>File&nbsp;List</span></a></li>
      <li><a href="globals.html"><span>File&nbsp;Members</span></a></li>
    </ul>
  </div>
<h1>src/qvblockprogramming/qvguiblocks/qvdesigner/slate/slatewindow.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*</span>
<a name="l00002"></a>00002 <span class="comment"> *      Copyright (C) 2008, 2009, 2010, 2011, 2012. PARP Research Group.</span>
<a name="l00003"></a>00003 <span class="comment"> *      &lt;http://perception.inf.um.es&gt;</span>
<a name="l00004"></a>00004 <span class="comment"> *      University of Murcia, Spain.</span>
<a name="l00005"></a>00005 <span class="comment"> *</span>
<a name="l00006"></a>00006 <span class="comment"> *      This file is part of the QVision library.</span>
<a name="l00007"></a>00007 <span class="comment"> *</span>
<a name="l00008"></a>00008 <span class="comment"> *      QVision is free software: you can redistribute it and/or modify</span>
<a name="l00009"></a>00009 <span class="comment"> *      it under the terms of the GNU Lesser General Public License as</span>
<a name="l00010"></a>00010 <span class="comment"> *      published by the Free Software Foundation, version 3 of the License.</span>
<a name="l00011"></a>00011 <span class="comment"> *</span>
<a name="l00012"></a>00012 <span class="comment"> *      QVision is distributed in the hope that it will be useful,</span>
<a name="l00013"></a>00013 <span class="comment"> *      but WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00014"></a>00014 <span class="comment"> *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span>
<a name="l00015"></a>00015 <span class="comment"> *      GNU Lesser General Public License for more details.</span>
<a name="l00016"></a>00016 <span class="comment"> *</span>
<a name="l00017"></a>00017 <span class="comment"> *      You should have received a copy of the GNU Lesser General Public</span>
<a name="l00018"></a>00018 <span class="comment"> *      License along with QVision. If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
<a name="l00019"></a>00019 <span class="comment"> */</span>
<a name="l00020"></a>00020 
<a name="l00021"></a>00021 
<a name="l00022"></a>00022 <span class="preprocessor">#include &lt;QtGui&gt;</span>
<a name="l00023"></a>00023 <span class="preprocessor">#include &lt;QDebug&gt;</span>
<a name="l00024"></a>00024 <span class="preprocessor">#include &lt;iostream&gt;</span>
<a name="l00025"></a>00025 
<a name="l00026"></a>00026 <span class="preprocessor">#include &quot;slatewindow.h&quot;</span>
<a name="l00027"></a>00027 <span class="preprocessor">#include &quot;sinclink.h&quot;</span>
<a name="l00028"></a>00028 <span class="preprocessor">#include &quot;asinclink.h&quot;</span>
<a name="l00029"></a>00029 <span class="preprocessor">#include &quot;sequenlink.h&quot;</span>
<a name="l00030"></a>00030 <span class="preprocessor">#include &quot;node.h&quot;</span>
<a name="l00031"></a>00031 <span class="preprocessor">#include &quot;groupnode.h&quot;</span>
<a name="l00032"></a>00032 <span class="preprocessor">#include &quot;inputnode.h&quot;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#include &quot;middlenode.h&quot;</span>
<a name="l00034"></a>00034 <span class="preprocessor">#include &quot;outputnode.h&quot;</span>
<a name="l00035"></a>00035 <span class="preprocessor">#include &quot;slateview.h&quot;</span>
<a name="l00036"></a>00036 <span class="preprocessor">#include &quot;insertaction.h&quot;</span>
<a name="l00037"></a>00037 
<a name="l00038"></a>00038 <span class="preprocessor">#include &lt;QVDesignerGUI&gt;</span>
<a name="l00039"></a>00039 <span class="comment">//#include &quot;../designergui.h&quot;</span>
<a name="l00040"></a>00040 <span class="preprocessor">#include &quot;../facade/itemproperties.h&quot;</span>
<a name="l00041"></a>00041 
<a name="l00042"></a>00042 
<a name="l00043"></a>00043 SlateWindow::SlateWindow(<a class="code" href="classQVDesignerGUI.html" title="Advanced graphic block oriented programming interface widget for QVision applications...">QVDesignerGUI</a> *desig, QWidget * parent): QMainWindow(parent), designer(desig)
<a name="l00044"></a>00044 {
<a name="l00045"></a>00045     scene = <span class="keyword">new</span> QGraphicsScene(-1180, -900, 3200, 2400);
<a name="l00046"></a>00046 
<a name="l00047"></a>00047     view = <span class="keyword">new</span> SlateView;
<a name="l00048"></a>00048     view-&gt;setScene(scene);
<a name="l00049"></a>00049     view-&gt;setDragMode(QGraphicsView::RubberBandDrag);
<a name="l00050"></a>00050     view-&gt;setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
<a name="l00051"></a>00051     view-&gt;setContextMenuPolicy(Qt::ActionsContextMenu);
<a name="l00052"></a>00052     setCentralWidget(view);
<a name="l00053"></a>00053 
<a name="l00054"></a>00054     minZ = 0;
<a name="l00055"></a>00055     maxZ = 0;
<a name="l00056"></a>00056     seqNumber = 0;
<a name="l00057"></a>00057 
<a name="l00058"></a>00058     createMenus();
<a name="l00059"></a>00059     createToolBars();
<a name="l00060"></a>00060 
<a name="l00061"></a>00061         statusbar = <span class="keyword">new</span> QStatusBar();
<a name="l00062"></a>00062         setStatusBar(statusbar);
<a name="l00063"></a>00063 
<a name="l00064"></a>00064     connect(scene, SIGNAL(selectionChanged()), <span class="keyword">this</span>, SLOT(updateActions()));
<a name="l00065"></a>00065 
<a name="l00066"></a>00066         scene-&gt;setBackgroundBrush(QPixmap(<span class="stringliteral">&quot;:/images/background1.png&quot;</span>));
<a name="l00067"></a>00067 
<a name="l00068"></a>00068     setWindowTitle(tr(<span class="stringliteral">&quot;Slate&quot;</span>));
<a name="l00069"></a>00069 
<a name="l00070"></a>00070         showMessage(<span class="stringliteral">&quot;Pulsa \&quot;Stop\&quot; para poder editar el ejemplo.&quot;</span>);
<a name="l00071"></a>00071 
<a name="l00072"></a>00072     updateActions();
<a name="l00073"></a>00073 }
<a name="l00074"></a>00074 
<a name="l00075"></a>00075 <span class="keywordtype">void</span> SlateWindow::closeEvent(QCloseEvent *)
<a name="l00076"></a>00076         {
<a name="l00077"></a>00077         emit closed();
<a name="l00078"></a>00078         }
<a name="l00079"></a>00079 
<a name="l00081"></a>00081 <span class="keywordtype">bool</span> SlateWindow::createLink(Node *fromNode, <span class="keywordtype">int</span> fromPoint, Node *toNode, <span class="keywordtype">int</span> toPoint)
<a name="l00082"></a>00082 {
<a name="l00083"></a>00083         <span class="comment">// si está en ejecución no se permite lincar</span>
<a name="l00084"></a>00084         <span class="keywordflow">if</span> (stopAction-&gt;isEnabled()) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00085"></a>00085 
<a name="l00086"></a>00086         uint fromId = 0, toId = 0;
<a name="l00087"></a>00087         fromId = fromNode-&gt;getId();
<a name="l00088"></a>00088         toId = toNode-&gt;getId();
<a name="l00089"></a>00089 
<a name="l00090"></a>00090         <span class="keywordtype">bool</span> sinc = addSLinkAction-&gt;isChecked();
<a name="l00091"></a>00091         <span class="keywordtype">bool</span> sequ = (!addSLinkAction-&gt;isChecked() &amp;&amp; !addALinkAction-&gt;isChecked());
<a name="l00092"></a>00092 
<a name="l00093"></a>00093         designer-&gt;addLink(fromId, fromNode-&gt;propName(fromPoint), toId, toNode-&gt;propName(toPoint), sinc, sequ);
<a name="l00094"></a>00094 
<a name="l00095"></a>00095 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00096"></a>00096 }
<a name="l00097"></a>00097 
<a name="l00098"></a>00098 <span class="keywordtype">void</span> SlateWindow::addLinkLine(uint fromId, QString fromProp, uint toId, QString toProp, <span class="keywordtype">bool</span> sinc, <span class="keywordtype">bool</span> sequential)
<a name="l00099"></a>00099 {
<a name="l00100"></a>00100         Link *link;
<a name="l00101"></a>00101         QString linkName = QString(<span class="stringliteral">&quot;%1&quot;</span>).arg(fromId) + <span class="stringliteral">&quot;[&quot;</span> + fromProp + <span class="stringliteral">&quot;] =&gt; &quot;</span> + QString(<span class="stringliteral">&quot;%1&quot;</span>).arg(toId) + <span class="stringliteral">&quot;[&quot;</span> + toProp + <span class="stringliteral">&quot;]&quot;</span>;
<a name="l00102"></a>00102 
<a name="l00103"></a>00103         <span class="keywordflow">if</span> ( insertNodes.contains(fromId) &amp;&amp; insertNodes.contains(toId) ) {
<a name="l00104"></a>00104                 Node *from = insertNodes.value(fromId);
<a name="l00105"></a>00105                 Node *to = insertNodes.value(toId);
<a name="l00106"></a>00106 
<a name="l00107"></a>00107                 <span class="keywordflow">if</span> (sequential) {
<a name="l00108"></a>00108                         link = <span class="keyword">new</span> SequenLink(from, fromProp, to, toProp, 0, scene);
<a name="l00109"></a>00109                         insertLinks.insert(linkName, link);
<a name="l00110"></a>00110                         link-&gt;trackNodes();
<a name="l00111"></a>00111                 }
<a name="l00112"></a>00112                 <span class="keywordflow">else</span> <span class="keywordflow">if</span> (sinc) {
<a name="l00113"></a>00113                         link = <span class="keyword">new</span> SincLink(from, fromProp, to, toProp, 0, scene);
<a name="l00114"></a>00114                         insertLinks.insert(linkName, link);
<a name="l00115"></a>00115                         link-&gt;trackNodes();
<a name="l00116"></a>00116                 }
<a name="l00117"></a>00117                 <span class="keywordflow">else</span> {
<a name="l00118"></a>00118                         link = <span class="keyword">new</span> AsincLink(from, fromProp, to, toProp, 0, scene);
<a name="l00119"></a>00119                         insertLinks.insert(linkName, link);
<a name="l00120"></a>00120                         link-&gt;trackNodes();
<a name="l00121"></a>00121                 }
<a name="l00122"></a>00122         }
<a name="l00123"></a>00123 }
<a name="l00124"></a>00124 
<a name="l00125"></a>00125 <span class="keywordtype">void</span> SlateWindow::delLinkLine(uint fromId, QString fromProp, uint toId, QString toProp)
<a name="l00126"></a>00126 {
<a name="l00127"></a>00127         QString linkName = QString(<span class="stringliteral">&quot;%1&quot;</span>).arg(fromId) + <span class="stringliteral">&quot;[&quot;</span> + fromProp + <span class="stringliteral">&quot;] =&gt; &quot;</span> + QString(<span class="stringliteral">&quot;%1&quot;</span>).arg(toId) + <span class="stringliteral">&quot;[&quot;</span> + toProp + <span class="stringliteral">&quot;]&quot;</span>;
<a name="l00128"></a>00128         <span class="keywordflow">if</span> (insertLinks.contains(linkName)) {
<a name="l00129"></a>00129                 <span class="keyword">delete</span> insertLinks.value(linkName);
<a name="l00130"></a>00130                 insertLinks.remove(linkName);
<a name="l00131"></a>00131         }
<a name="l00132"></a>00132 }
<a name="l00133"></a>00133 
<a name="l00134"></a>00134 <span class="keywordtype">void</span> SlateWindow::insertItem(QString type)
<a name="l00135"></a>00135 {
<a name="l00136"></a>00136         QString name = type.toLower();
<a name="l00137"></a>00137         name.replace(<span class="charliteral">&#39;&lt;&#39;</span>, <span class="charliteral">&#39;_&#39;</span>);
<a name="l00138"></a>00138         name.replace(<span class="charliteral">&#39;,&#39;</span>, <span class="charliteral">&#39;_&#39;</span>);
<a name="l00139"></a>00139         name.replace(<span class="charliteral">&#39;&gt;&#39;</span>, <span class="charliteral">&#39;_&#39;</span>);
<a name="l00140"></a>00140         name.replace(<span class="charliteral">&#39; &#39;</span>, <span class="stringliteral">&quot;&quot;</span>);
<a name="l00141"></a>00141 
<a name="l00142"></a>00142         designer-&gt;addItem(type, name);
<a name="l00143"></a>00143 }
<a name="l00144"></a>00144 
<a name="l00145"></a>00145 <span class="keywordtype">void</span> SlateWindow::setName(Node *item, QString name)
<a name="l00146"></a>00146 {
<a name="l00147"></a>00147         designer-&gt;setName(insertNodes.key(item), name); <span class="comment">// si no esta el item devuelve 0, que es id nulo</span>
<a name="l00148"></a>00148 }
<a name="l00149"></a>00149 
<a name="l00150"></a>00150 <span class="keywordtype">void</span> SlateWindow::setItemName(uint <span class="keywordtype">id</span>, QString name)
<a name="l00151"></a>00151 {
<a name="l00152"></a>00152         <span class="keywordflow">if</span> (insertNodes.contains(<span class="keywordtype">id</span>))
<a name="l00153"></a>00153                 insertNodes.value(<span class="keywordtype">id</span>)-&gt;setName(name);
<a name="l00154"></a>00154 }
<a name="l00155"></a>00155 
<a name="l00156"></a>00156 <span class="keywordtype">void</span> SlateWindow::addItemNode(QString type, QString name, uint <span class="keywordtype">id</span>, ItemProperties *item, uint lastId)
<a name="l00157"></a>00157 {
<a name="l00159"></a>00159         <span class="keywordtype">bool</span> inputItemsContainsType = <span class="keyword">false</span>;
<a name="l00160"></a>00160         <span class="keywordflow">foreach</span>(QList&lt;QString&gt; groupItems, designer-&gt;getInputItemTypes().values())
<a name="l00161"></a>00161                 <span class="keywordflow">if</span> (groupItems.contains(type)) {
<a name="l00162"></a>00162                         inputItemsContainsType = <span class="keyword">true</span>;
<a name="l00163"></a>00163                         <span class="keywordflow">break</span>;
<a name="l00164"></a>00164                 }
<a name="l00165"></a>00165         <span class="keywordflow">if</span> (inputItemsContainsType) {
<a name="l00166"></a>00166                 InputNode *node = <span class="keyword">new</span> InputNode(*item, name, <span class="keywordtype">id</span>, <span class="keyword">this</span>, 0, scene);
<a name="l00167"></a>00167                 insertNodes.insert(<span class="keywordtype">id</span>, node);
<a name="l00168"></a>00168                 setupNode(node);
<a name="l00169"></a>00169                 <span class="keywordflow">if</span> (insertNodesPos.contains(lastId)) {
<a name="l00170"></a>00170                         node-&gt;setPos(insertNodesPos.value(lastId));
<a name="l00171"></a>00171                         insertNodesPos.remove(lastId);
<a name="l00172"></a>00172                         insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00173"></a>00173                 }
<a name="l00174"></a>00174                 <span class="keywordflow">else</span>
<a name="l00175"></a>00175                         insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00176"></a>00176         }
<a name="l00177"></a>00177         <span class="keywordflow">else</span> {
<a name="l00178"></a>00178                 <span class="keywordtype">bool</span> middleItemsContainsType = <span class="keyword">false</span>;
<a name="l00179"></a>00179                 <span class="keywordflow">foreach</span>(QList&lt;QString&gt; groupItems, designer-&gt;getMiddleItemTypes().values())
<a name="l00180"></a>00180                         <span class="keywordflow">if</span> (groupItems.contains(type)) {
<a name="l00181"></a>00181                                 middleItemsContainsType = <span class="keyword">true</span>;
<a name="l00182"></a>00182                                 <span class="keywordflow">break</span>;
<a name="l00183"></a>00183                         }
<a name="l00184"></a>00184                 <span class="keywordflow">if</span> (middleItemsContainsType) {
<a name="l00185"></a>00185                         MiddleNode *node = <span class="keyword">new</span> MiddleNode(*item, name, <span class="keywordtype">id</span>, <span class="keyword">this</span>, 0, scene);
<a name="l00186"></a>00186                         insertNodes.insert(<span class="keywordtype">id</span>, node);
<a name="l00187"></a>00187                         setupNode(node);
<a name="l00188"></a>00188                         <span class="keywordflow">if</span> (insertNodesPos.contains(lastId)) {
<a name="l00189"></a>00189                                 node-&gt;setPos(insertNodesPos.value(lastId));
<a name="l00190"></a>00190                                 insertNodesPos.remove(lastId);
<a name="l00191"></a>00191                                 insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00192"></a>00192                         }
<a name="l00193"></a>00193                         <span class="keywordflow">else</span>
<a name="l00194"></a>00194                                 insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00195"></a>00195                 }
<a name="l00196"></a>00196                 <span class="keywordflow">else</span> {
<a name="l00197"></a>00197                         <span class="keywordtype">bool</span> outputItemsContainsType = <span class="keyword">false</span>;
<a name="l00198"></a>00198                         <span class="keywordflow">foreach</span>(QList&lt;QString&gt; groupItems, designer-&gt;getOutputItemTypes().values())
<a name="l00199"></a>00199                                 <span class="keywordflow">if</span> (groupItems.contains(type)) {
<a name="l00200"></a>00200                                         outputItemsContainsType = <span class="keyword">true</span>;
<a name="l00201"></a>00201                                         <span class="keywordflow">break</span>;
<a name="l00202"></a>00202                                 }
<a name="l00203"></a>00203                         <span class="keywordflow">if</span> (outputItemsContainsType) {
<a name="l00204"></a>00204                                 OutputNode *node = <span class="keyword">new</span> OutputNode(*item, name, <span class="keywordtype">id</span>, <span class="keyword">this</span>, 0, scene);
<a name="l00205"></a>00205                                 insertNodes.insert(<span class="keywordtype">id</span>, node);
<a name="l00206"></a>00206                                 setupNode(node);
<a name="l00207"></a>00207                                 <span class="keywordflow">if</span> (insertNodesPos.contains(lastId)) {
<a name="l00208"></a>00208                                         node-&gt;setPos(insertNodesPos.value(lastId));
<a name="l00209"></a>00209                                         insertNodesPos.remove(lastId);
<a name="l00210"></a>00210                                         insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00211"></a>00211                                 }
<a name="l00212"></a>00212                                 <span class="keywordflow">else</span>
<a name="l00213"></a>00213                                         insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00214"></a>00214                         }
<a name="l00215"></a>00215                 }
<a name="l00216"></a>00216         }
<a name="l00217"></a>00217 }
<a name="l00218"></a>00218 
<a name="l00219"></a>00219 <span class="keywordtype">void</span> SlateWindow::delItemNode(uint <span class="keywordtype">id</span>)
<a name="l00220"></a>00220 {
<a name="l00221"></a>00221         <span class="keywordflow">if</span> (insertNodes.contains(<span class="keywordtype">id</span>)) {
<a name="l00222"></a>00222                 insertNodesPos.remove(<span class="keywordtype">id</span>);      <span class="comment">// guarda la posición del nodo, por si se vuelve a insertar uno con el mismo nombre</span>
<a name="l00223"></a>00223                 insertNodesPos.insert(<span class="keywordtype">id</span>, insertNodes.value(<span class="keywordtype">id</span>)-&gt;pos());
<a name="l00224"></a>00224                 <span class="keyword">delete</span> insertNodes.value(<span class="keywordtype">id</span>);
<a name="l00225"></a>00225                 insertNodes.remove(<span class="keywordtype">id</span>);
<a name="l00226"></a>00226         }
<a name="l00227"></a>00227 }
<a name="l00228"></a>00228 
<a name="l00229"></a>00229 <span class="keywordtype">void</span> SlateWindow::addProperty(uint <span class="keywordtype">id</span>, QString propName, <span class="keywordtype">int</span> type, <span class="keywordtype">bool</span> in, <span class="keywordtype">bool</span> out)
<a name="l00230"></a>00230 {
<a name="l00231"></a>00231         <span class="keywordflow">if</span> (insertNodes.contains(<span class="keywordtype">id</span>)) {
<a name="l00232"></a>00232                 insertNodes.value(<span class="keywordtype">id</span>)-&gt;insertProperty(propName, type, in, out);
<a name="l00233"></a>00233         }
<a name="l00234"></a>00234 }
<a name="l00235"></a>00235 
<a name="l00236"></a>00236 <span class="keywordtype">void</span> SlateWindow::delProperty(uint <span class="keywordtype">id</span>, QString propName)
<a name="l00237"></a>00237 {
<a name="l00238"></a>00238         <span class="keywordflow">if</span> (insertNodes.contains(<span class="keywordtype">id</span>)) {
<a name="l00239"></a>00239                 insertNodes.value(<span class="keywordtype">id</span>)-&gt;removeProperty(propName);
<a name="l00240"></a>00240         }
<a name="l00241"></a>00241 }
<a name="l00242"></a>00242 
<a name="l00243"></a>00243 <span class="keywordtype">void</span> SlateWindow::del()
<a name="l00244"></a>00244 {
<a name="l00245"></a>00245         <span class="comment">// primero borro solo los links, ya que al borrar un nodo pueden desaparecer links seleccionados, que se intentarian borrar y daría un core</span>
<a name="l00246"></a>00246         <span class="keywordflow">foreach</span>(QGraphicsItem *item, scene-&gt;selectedItems()) {
<a name="l00247"></a>00247         Link *link = <span class="keyword">dynamic_cast&lt;</span>Link *<span class="keyword">&gt;</span>(item);
<a name="l00248"></a>00248 
<a name="l00249"></a>00249         <span class="keywordflow">if</span> (link &amp;&amp; (link-&gt;fromNode() != NULL) &amp;&amp; (link-&gt;toNode() != NULL)) {
<a name="l00250"></a>00250                         uint fromId = 0, toId = 0;
<a name="l00251"></a>00251                         fromId = link-&gt;fromNode()-&gt;getId();
<a name="l00252"></a>00252                         toId = link-&gt;toNode()-&gt;getId();
<a name="l00253"></a>00253 
<a name="l00254"></a>00254                         designer-&gt;delLink(fromId, link-&gt;fromProp(), toId, link-&gt;toProp());
<a name="l00255"></a>00255         }
<a name="l00256"></a>00256     }
<a name="l00257"></a>00257 
<a name="l00258"></a>00258         <span class="comment">// luego borro los grupos seleccionados</span>
<a name="l00259"></a>00259         <span class="keywordflow">foreach</span>(QGraphicsItem *item, scene-&gt;selectedItems()) {
<a name="l00260"></a>00260                 GroupNode *node = <span class="keyword">dynamic_cast&lt;</span>GroupNode *<span class="keyword">&gt;</span>(item);
<a name="l00261"></a>00261 
<a name="l00262"></a>00262                 <span class="keywordflow">if</span> (node) {
<a name="l00263"></a>00263                         <span class="comment">// si es subgrupo de otro grupo, todos los elementos internos de este pasan a formar parte del padre</span>
<a name="l00264"></a>00264                         <span class="comment">// y el grupo borrado se desregistra como subgrupo del padre</span>
<a name="l00265"></a>00265                         GroupInfo delGroupInfo = createdGroupInfos[(Node *)node]; <span class="comment">// obtengo el GroupInfo del grupo a borrar</span>
<a name="l00266"></a>00266                         <span class="keywordflow">foreach</span>(Node *group, createdGroupInfos.keys()) { <span class="comment">// para cada grupo creado en la pizarra</span>
<a name="l00267"></a>00267                                 GroupInfo groupInfo = createdGroupInfos[group];
<a name="l00268"></a>00268                                 <span class="keywordflow">foreach</span>(uint subgroupId, groupInfo.getSubgroups())
<a name="l00269"></a>00269                                         <span class="keywordflow">if</span> (subgroupId == delGroupInfo.getId()) { <span class="comment">// si contiene como subgrupo al grupo a borrar</span>
<a name="l00270"></a>00270                                                 <span class="keywordflow">foreach</span>(uint internalNode, delGroupInfo.getNodes()) <span class="comment">// le añado los nodos de este</span>
<a name="l00271"></a>00271                                                         groupInfo.addNode(internalNode);
<a name="l00272"></a>00272                                                 <span class="keywordflow">foreach</span>(uint internalSubgroup, delGroupInfo.getSubgroups()) <span class="comment">// le añado los subgrupos de este</span>
<a name="l00273"></a>00273                                                         groupInfo.addSubgroup(internalSubgroup);
<a name="l00274"></a>00274                                                 groupInfo.delSubgroup(delGroupInfo.getId()); <span class="comment">// quito el grupo a borrar como su subgrupo</span>
<a name="l00275"></a>00275                                                 createdGroupInfos.insert(group, groupInfo); <span class="comment">// y actualizo los cambios</span>
<a name="l00276"></a>00276                                         }
<a name="l00277"></a>00277                         }
<a name="l00278"></a>00278 
<a name="l00279"></a>00279                         createdGroupInfos.remove(node);
<a name="l00280"></a>00280                         createdGroups.remove(node-&gt;getId());
<a name="l00281"></a>00281                         <span class="keyword">delete</span> node;
<a name="l00282"></a>00282                 }
<a name="l00283"></a>00283     }
<a name="l00284"></a>00284 
<a name="l00285"></a>00285         <span class="comment">// y por último los nodos reatantes</span>
<a name="l00286"></a>00286         <span class="keywordflow">foreach</span>(QGraphicsItem *item, scene-&gt;selectedItems()) {
<a name="l00287"></a>00287                 Node *node = <span class="keyword">dynamic_cast&lt;</span>InputNode *<span class="keyword">&gt;</span>(item);
<a name="l00288"></a>00288                 <span class="keywordflow">if</span> (!node) node = <span class="keyword">dynamic_cast&lt;</span>MiddleNode *<span class="keyword">&gt;</span>(item);
<a name="l00289"></a>00289                 <span class="keywordflow">if</span> (!node) node = <span class="keyword">dynamic_cast&lt;</span>OutputNode *<span class="keyword">&gt;</span>(item);
<a name="l00290"></a>00290 
<a name="l00291"></a>00291                 <span class="keywordflow">if</span> (node) {
<a name="l00292"></a>00292                         uint itemnode = 0;
<a name="l00293"></a>00293                         itemnode = node-&gt;getId();
<a name="l00294"></a>00294                         designer-&gt;delItem(itemnode);
<a name="l00295"></a>00295                 }
<a name="l00296"></a>00296     }
<a name="l00297"></a>00297 }
<a name="l00298"></a>00298 
<a name="l00299"></a>00299 <span class="keywordtype">void</span> SlateWindow::join()
<a name="l00300"></a>00300 {
<a name="l00301"></a>00301         QList&lt;QGraphicsItem *&gt; group = selectedNodeGroup();
<a name="l00302"></a>00302 
<a name="l00303"></a>00303         <span class="comment">// obtengo la posición media de los items a agrupar, para situar el grupo lo más centrado posible</span>
<a name="l00304"></a>00304         QPointF middlePos;
<a name="l00305"></a>00305         <span class="keywordtype">int</span> count = 0;
<a name="l00306"></a>00306         <span class="keywordflow">foreach</span> (QGraphicsItem *item, group) {
<a name="l00307"></a>00307                 Node *itemNode = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(item);
<a name="l00308"></a>00308                 <span class="keywordflow">if</span> (itemNode) {
<a name="l00309"></a>00309                         middlePos += itemNode-&gt;pos();
<a name="l00310"></a>00310                         count++;
<a name="l00311"></a>00311                 }
<a name="l00312"></a>00312         }
<a name="l00313"></a>00313         middlePos /= count;
<a name="l00314"></a>00314 
<a name="l00315"></a>00315         <span class="comment">// creo el nuevo grupo</span>
<a name="l00316"></a>00316     GroupNode *node = <span class="keyword">new</span> GroupNode(<span class="stringliteral">&quot;Group&quot;</span>, <span class="keyword">this</span>, 0, scene);
<a name="l00317"></a>00317         node-&gt;setPos(middlePos);
<a name="l00318"></a>00318 
<a name="l00319"></a>00319         <span class="comment">// si los items seleccionados estaban ya dentro de otro grupo, este se añade a el (sino a la escena)</span>
<a name="l00320"></a>00320         <span class="keywordflow">if</span> ( !group.isEmpty() &amp;&amp; group.first() &amp;&amp; group.first()-&gt;parentItem() ) {
<a name="l00321"></a>00321                 GroupNode *parentNode = <span class="keyword">dynamic_cast&lt;</span>GroupNode *<span class="keyword">&gt;</span>(group.first()-&gt;parentItem());
<a name="l00322"></a>00322                 <span class="keywordflow">if</span> (parentNode) parentNode-&gt;addNode(node);
<a name="l00323"></a>00323         }
<a name="l00324"></a>00324 
<a name="l00325"></a>00325         <span class="comment">// para cada item si es un nodo lo añado al nuevo grupo</span>
<a name="l00326"></a>00326         <span class="keywordflow">foreach</span> (QGraphicsItem *item, group) {
<a name="l00327"></a>00327                 Node *itemNode = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(item);
<a name="l00328"></a>00328                 <span class="keywordflow">if</span> (itemNode) {
<a name="l00329"></a>00329                         node-&gt;addNode(itemNode);
<a name="l00330"></a>00330 
<a name="l00331"></a>00331                         <span class="comment">//se actualiza el tamaño de sus links</span>
<a name="l00332"></a>00332                         <span class="comment">//y si la otra punta no se va a meter al grupo pasa a formar parte de este</span>
<a name="l00333"></a>00333                         <span class="keywordflow">foreach</span> (Link *link, itemNode-&gt;getInLinks()) {
<a name="l00334"></a>00334                                 Node *other = link-&gt;fromNode();
<a name="l00335"></a>00335                                 <span class="keywordflow">if</span> (group.contains(other)) {
<a name="l00336"></a>00336                                         QPen pen = link-&gt;pen();
<a name="l00337"></a>00337                                         pen.setWidthF(pen.width()*0.5);
<a name="l00338"></a>00338                                         link-&gt;setPen(pen);
<a name="l00339"></a>00339                                         link-&gt;update();
<a name="l00340"></a>00340                                 }
<a name="l00341"></a>00341                         }
<a name="l00342"></a>00342                         <span class="keywordflow">foreach</span> (Link *link, itemNode-&gt;getOutLinks()) {
<a name="l00343"></a>00343                                 Node *other = link-&gt;toNode();
<a name="l00344"></a>00344                                 <span class="keywordflow">if</span> (group.contains(other)) {
<a name="l00345"></a>00345                                         QPen pen = link-&gt;pen();
<a name="l00346"></a>00346                                         pen.setWidthF(pen.width()*0.5);
<a name="l00347"></a>00347                                         link-&gt;setPen(pen);
<a name="l00348"></a>00348                                         link-&gt;update();
<a name="l00349"></a>00349                                 }
<a name="l00350"></a>00350                         }
<a name="l00351"></a>00351                         itemNode-&gt;updateLinksPos(); <span class="comment">// para que se actualiza la posición y tamaño de los links del nodo</span>
<a name="l00352"></a>00352                 }
<a name="l00353"></a>00353         }
<a name="l00354"></a>00354 
<a name="l00355"></a>00355         createdGroupInfos.insert(node, node-&gt;getInfo());
<a name="l00356"></a>00356         createdGroups.insert(node-&gt;getId(), node);
<a name="l00357"></a>00357 }
<a name="l00358"></a>00358 
<a name="l00359"></a>00359 <span class="keywordtype">void</span> SlateWindow::bringToFront()
<a name="l00360"></a>00360 {
<a name="l00361"></a>00361     maxZ += 2; <span class="comment">// dos, uno para el y otro para sus link que serán: el + 1</span>
<a name="l00362"></a>00362     setZValue(maxZ);
<a name="l00363"></a>00363 }
<a name="l00364"></a>00364 
<a name="l00365"></a>00365 <span class="keywordtype">void</span> SlateWindow::sendToBack()
<a name="l00366"></a>00366 {
<a name="l00367"></a>00367     minZ += 2; <span class="comment">// dos, uno para el y otro para sus link que serán: el + 1</span>
<a name="l00368"></a>00368     setZValue(minZ);
<a name="l00369"></a>00369 }
<a name="l00370"></a>00370 
<a name="l00371"></a>00371 <span class="keywordtype">void</span> SlateWindow::run()
<a name="l00372"></a>00372 {
<a name="l00373"></a>00373         <span class="keywordflow">foreach</span> (QAction *action, insertMenu-&gt;actions()) {
<a name="l00374"></a>00374                 action-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00375"></a>00375         }
<a name="l00376"></a>00376         <span class="keywordflow">foreach</span> (QMenu *submenu, insertSubmenus) {
<a name="l00377"></a>00377                 submenu-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00378"></a>00378                 <span class="keywordflow">foreach</span> (QAction *action, submenu-&gt;actions()) {
<a name="l00379"></a>00379                         action-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00380"></a>00380                 }
<a name="l00381"></a>00381         }
<a name="l00382"></a>00382 
<a name="l00383"></a>00383         deleteAction-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00384"></a>00384         openAction-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00385"></a>00385 
<a name="l00386"></a>00386         runAction-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00387"></a>00387         stopAction-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00388"></a>00388         designer-&gt;run();
<a name="l00389"></a>00389 }
<a name="l00390"></a>00390 
<a name="l00391"></a>00391 <span class="keywordtype">void</span> SlateWindow::stop()
<a name="l00392"></a>00392 {
<a name="l00393"></a>00393         designer-&gt;stop();
<a name="l00394"></a>00394         stopAction-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00395"></a>00395         runAction-&gt;setChecked(<span class="keyword">false</span>);
<a name="l00396"></a>00396         runAction-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00397"></a>00397 
<a name="l00398"></a>00398     <span class="keywordtype">bool</span> hasSelection = !scene-&gt;selectedItems().isEmpty();
<a name="l00399"></a>00399         deleteAction-&gt;setEnabled(hasSelection);
<a name="l00400"></a>00400         openAction-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00401"></a>00401 
<a name="l00402"></a>00402         <span class="keywordflow">foreach</span> (QAction *action, insertMenu-&gt;actions()) {
<a name="l00403"></a>00403                 action-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00404"></a>00404         }
<a name="l00405"></a>00405         <span class="keywordflow">foreach</span> (QMenu *submenu, insertSubmenus) {
<a name="l00406"></a>00406                 <span class="keywordflow">foreach</span> (QAction *action, submenu-&gt;actions()) {
<a name="l00407"></a>00407                         action-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00408"></a>00408                 }
<a name="l00409"></a>00409                 submenu-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00410"></a>00410         }
<a name="l00411"></a>00411 }
<a name="l00412"></a>00412 
<a name="l00413"></a>00413 <span class="keywordtype">void</span> SlateWindow::setZValue(<span class="keywordtype">int</span> z)
<a name="l00414"></a>00414 {
<a name="l00415"></a>00415     Node *node = selectedNode();
<a name="l00416"></a>00416     <span class="keywordflow">if</span> (node) {
<a name="l00417"></a>00417         node-&gt;setZValue(z);
<a name="l00418"></a>00418                 node-&gt;updateLinksPos();
<a name="l00419"></a>00419         }
<a name="l00420"></a>00420 }
<a name="l00421"></a>00421 
<a name="l00422"></a>00422 <span class="keywordtype">void</span> SlateWindow::showProperties()
<a name="l00423"></a>00423 {
<a name="l00424"></a>00424     Node *node = selectedNode();
<a name="l00425"></a>00425 
<a name="l00426"></a>00426     <span class="keywordflow">if</span> (node) showProperties(node);
<a name="l00427"></a>00427 }
<a name="l00428"></a>00428 
<a name="l00429"></a>00429 <span class="keywordtype">void</span> SlateWindow::showProperties(Node *node)
<a name="l00430"></a>00430 {
<a name="l00431"></a>00431         uint itemnode = 0;
<a name="l00432"></a>00432         itemnode = node-&gt;getId();
<a name="l00433"></a>00433 
<a name="l00434"></a>00434         designer-&gt;showProperties(itemnode);
<a name="l00435"></a>00435 }
<a name="l00436"></a>00436 
<a name="l00437"></a>00437 <span class="keywordtype">void</span> SlateWindow::updateActions()
<a name="l00438"></a>00438 {
<a name="l00439"></a>00439     <span class="keywordtype">bool</span> hasSelection = !scene-&gt;selectedItems().isEmpty();
<a name="l00440"></a>00440     <span class="keywordtype">bool</span> isNode = (selectedNode() != 0);
<a name="l00441"></a>00441 <span class="comment">//      bool isNodePair = (selectedNodePair() != NodePair());</span>
<a name="l00442"></a>00442         <span class="keywordtype">bool</span> isNodeGroup = <span class="keyword">false</span>;
<a name="l00443"></a>00443         <span class="keywordtype">int</span> count = 0;
<a name="l00444"></a>00444         <span class="keywordflow">foreach</span> (QGraphicsItem *item, selectedNodeGroup())
<a name="l00445"></a>00445                 <span class="keywordflow">if</span> (dynamic_cast&lt;Node *&gt;(item)) count++;
<a name="l00446"></a>00446         <span class="keywordflow">if</span> (count &gt; 0) isNodeGroup = <span class="keyword">true</span>;
<a name="l00447"></a>00447 
<a name="l00448"></a>00448         joinAction-&gt;setEnabled(isNodeGroup);
<a name="l00449"></a>00449         <span class="comment">// si está en ejecución no se permite borrar</span>
<a name="l00450"></a>00450     <span class="keywordflow">if</span> (runAction-&gt;isEnabled()) {
<a name="l00451"></a>00451                 deleteAction-&gt;setEnabled(hasSelection);
<a name="l00452"></a>00452                 openAction-&gt;setEnabled(<span class="keyword">true</span>);
<a name="l00453"></a>00453         }
<a name="l00454"></a>00454     bringToFrontAction-&gt;setEnabled(isNode);
<a name="l00455"></a>00455     sendToBackAction-&gt;setEnabled(isNode);
<a name="l00456"></a>00456     propertiesAction-&gt;setEnabled(isNode);
<a name="l00457"></a>00457 
<a name="l00458"></a>00458     <span class="keywordflow">foreach</span> (QAction *action, view-&gt;actions())
<a name="l00459"></a>00459         view-&gt;removeAction(action);
<a name="l00460"></a>00460 
<a name="l00461"></a>00461     <span class="keywordflow">foreach</span> (QAction *action, editMenu-&gt;actions()) {
<a name="l00462"></a>00462         <span class="keywordflow">if</span> (action-&gt;isEnabled())
<a name="l00463"></a>00463             view-&gt;addAction(action);
<a name="l00464"></a>00464     }
<a name="l00465"></a>00465 
<a name="l00466"></a>00466         <span class="keywordflow">if</span> (!hasSelection) {
<a name="l00467"></a>00467                 <span class="comment">// añado las acciones del menu insertar al desplegable del botón derecho (de dos formas distintas)</span>
<a name="l00468"></a>00468                 QAction *insertTitle = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;Insert&quot;</span>), <span class="keyword">this</span>);
<a name="l00469"></a>00469                 insertTitle-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00470"></a>00470                 QFont font(insertTitle-&gt;font());
<a name="l00471"></a>00471                 font.setWeight(QFont::Black);
<a name="l00472"></a>00472                 font.setStyle(QFont::StyleItalic);
<a name="l00473"></a>00473                 insertTitle-&gt;setFont(font);
<a name="l00474"></a>00474                 view-&gt;addAction(insertTitle);
<a name="l00475"></a>00475                 view-&gt;addActions(insertMenu-&gt;actions());
<a name="l00476"></a>00476         }
<a name="l00477"></a>00477 }
<a name="l00478"></a>00478 
<a name="l00479"></a>00479 <span class="keywordtype">void</span> SlateWindow::clearSelection()
<a name="l00480"></a>00480 {
<a name="l00481"></a>00481         scene-&gt;clearSelection();
<a name="l00482"></a>00482 }
<a name="l00483"></a>00483 
<a name="l00484"></a>00484 <span class="keywordtype">bool</span> SlateWindow::isSelected(QGraphicsItem *item)
<a name="l00485"></a>00485 {
<a name="l00486"></a>00486         <span class="keywordflow">return</span> scene-&gt;selectedItems().contains(item);
<a name="l00487"></a>00487 }
<a name="l00488"></a>00488 
<a name="l00489"></a>00489 <span class="keywordtype">void</span> SlateWindow::setupNode(Node *node)
<a name="l00490"></a>00490 {
<a name="l00491"></a>00491     node-&gt;setPos( QPoint(10 + (seqNumber % 10) * 6, 20 + (seqNumber % 10) * 6) );
<a name="l00492"></a>00492     ++seqNumber;
<a name="l00493"></a>00493 
<a name="l00494"></a>00494     clearSelection();
<a name="l00495"></a>00495     node-&gt;setSelected(<span class="keyword">true</span>);
<a name="l00496"></a>00496     bringToFront();
<a name="l00497"></a>00497 }
<a name="l00498"></a>00498 
<a name="l00499"></a>00499 <span class="keywordtype">void</span> SlateWindow::createMenus()
<a name="l00500"></a>00500 {
<a name="l00502"></a>00502     exitAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;E&amp;xit&quot;</span>), <span class="keyword">this</span>);
<a name="l00503"></a>00503     exitAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+Q&quot;</span>));
<a name="l00504"></a>00504     connect(exitAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(close()));
<a name="l00505"></a>00505 
<a name="l00506"></a>00506     addALinkAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Asynchronous Link Mode&quot;</span>), <span class="keyword">this</span>);
<a name="l00507"></a>00507     addALinkAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/alink.png&quot;</span>));
<a name="l00508"></a>00508     addALinkAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+A&quot;</span>));
<a name="l00509"></a>00509         addALinkAction-&gt;setCheckable(<span class="keyword">true</span>); <span class="comment">// para que se mantenga pulsada</span>
<a name="l00510"></a>00510         addALinkAction-&gt;setChecked(<span class="keyword">true</span>); <span class="comment">// por defecto está seleccionado asincrono</span>
<a name="l00511"></a>00511 
<a name="l00512"></a>00512     addSLinkAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Synchronous Link Mode&quot;</span>), <span class="keyword">this</span>);
<a name="l00513"></a>00513     addSLinkAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/slink.png&quot;</span>));
<a name="l00514"></a>00514     addSLinkAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+S&quot;</span>));
<a name="l00515"></a>00515         addSLinkAction-&gt;setCheckable(<span class="keyword">true</span>); <span class="comment">// para que se mantenga pulsada</span>
<a name="l00516"></a>00516 
<a name="l00517"></a>00517     addQLinkAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;Se&amp;quential Link Mode&quot;</span>), <span class="keyword">this</span>);
<a name="l00518"></a>00518     addQLinkAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/qlink.png&quot;</span>));
<a name="l00519"></a>00519     addQLinkAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+Q&quot;</span>));
<a name="l00520"></a>00520         addQLinkAction-&gt;setCheckable(<span class="keyword">true</span>); <span class="comment">// para que se mantenga pulsada</span>
<a name="l00521"></a>00521 
<a name="l00522"></a>00522         <span class="comment">// con esto conseguimos meterlas en un grupo exclusivo, o una o la otra</span>
<a name="l00523"></a>00523         linkGroup = <span class="keyword">new</span> QActionGroup(<span class="keyword">this</span>);
<a name="l00524"></a>00524         linkGroup-&gt;setExclusive(<span class="keyword">true</span>);
<a name="l00525"></a>00525         linkGroup-&gt;addAction(addALinkAction);
<a name="l00526"></a>00526         linkGroup-&gt;addAction(addSLinkAction);
<a name="l00527"></a>00527         linkGroup-&gt;addAction(addQLinkAction);
<a name="l00528"></a>00528 
<a name="l00529"></a>00529 
<a name="l00530"></a>00530     joinAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Join&quot;</span>), <span class="keyword">this</span>);
<a name="l00531"></a>00531     joinAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/join.png&quot;</span>));
<a name="l00532"></a>00532     joinAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+J&quot;</span>));
<a name="l00533"></a>00533     connect(joinAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(join()));
<a name="l00534"></a>00534 
<a name="l00535"></a>00535     deleteAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Delete&quot;</span>), <span class="keyword">this</span>);
<a name="l00536"></a>00536     deleteAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/delete.png&quot;</span>));
<a name="l00537"></a>00537     deleteAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Del&quot;</span>));
<a name="l00538"></a>00538         deleteAction-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00539"></a>00539     connect(deleteAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(del()));
<a name="l00540"></a>00540 
<a name="l00541"></a>00541     bringToFrontAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;Bring to &amp;Front&quot;</span>), <span class="keyword">this</span>);
<a name="l00542"></a>00542     bringToFrontAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/bringtofront.png&quot;</span>));
<a name="l00543"></a>00543     connect(bringToFrontAction, SIGNAL(triggered()),<span class="keyword">this</span>, SLOT(bringToFront()));
<a name="l00544"></a>00544 
<a name="l00545"></a>00545     sendToBackAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Send to Back&quot;</span>), <span class="keyword">this</span>);
<a name="l00546"></a>00546     sendToBackAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/sendtoback.png&quot;</span>));
<a name="l00547"></a>00547     connect(sendToBackAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(sendToBack()));
<a name="l00548"></a>00548 
<a name="l00549"></a>00549     propertiesAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;P&amp;roperties...&quot;</span>), <span class="keyword">this</span>);
<a name="l00550"></a>00550     connect(propertiesAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(showProperties()));
<a name="l00551"></a>00551 
<a name="l00552"></a>00552     runAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Run&quot;</span>), <span class="keyword">this</span>);
<a name="l00553"></a>00553     runAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/run.png&quot;</span>));
<a name="l00554"></a>00554         runAction-&gt;setCheckable(<span class="keyword">true</span>); <span class="comment">// para que se mantenga pulsada</span>
<a name="l00555"></a>00555         runAction-&gt;setChecked(<span class="keyword">true</span>); <span class="comment">// porque comienza en ejecución</span>
<a name="l00556"></a>00556         runAction-&gt;setEnabled(<span class="keyword">false</span>); <span class="comment">// porque comienza en ejecución</span>
<a name="l00557"></a>00557     connect(runAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(run()));
<a name="l00558"></a>00558 
<a name="l00559"></a>00559     stopAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Stop&quot;</span>), <span class="keyword">this</span>);
<a name="l00560"></a>00560     stopAction-&gt;setIcon(QIcon(<span class="stringliteral">&quot;:/images/stop.png&quot;</span>));
<a name="l00561"></a>00561         stopAction-&gt;setEnabled(<span class="keyword">true</span>); <span class="comment">// porque comienza en ejecución</span>
<a name="l00562"></a>00562     connect(stopAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(stop()));
<a name="l00563"></a>00563 
<a name="l00564"></a>00564     exportAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Export&quot;</span>), <span class="keyword">this</span>);
<a name="l00565"></a>00565     exportAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+E&quot;</span>));
<a name="l00566"></a>00566     connect(exportAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(exportAs()));
<a name="l00567"></a>00567 
<a name="l00568"></a>00568     saveAsAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Save As&quot;</span>), <span class="keyword">this</span>);
<a name="l00569"></a>00569     saveAsAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+S&quot;</span>));
<a name="l00570"></a>00570     connect(saveAsAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(saveAs()));
<a name="l00571"></a>00571 
<a name="l00572"></a>00572     openAction = <span class="keyword">new</span> QAction(tr(<span class="stringliteral">&quot;&amp;Load&quot;</span>), <span class="keyword">this</span>);
<a name="l00573"></a>00573     openAction-&gt;setShortcut(tr(<span class="stringliteral">&quot;Ctrl+L&quot;</span>));
<a name="l00574"></a>00574         openAction-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00575"></a>00575     connect(openAction, SIGNAL(triggered()), <span class="keyword">this</span>, SLOT(open()));
<a name="l00576"></a>00576 
<a name="l00577"></a>00577     fileMenu = menuBar()-&gt;addMenu(tr(<span class="stringliteral">&quot;&amp;File&quot;</span>));
<a name="l00578"></a>00578         fileMenu-&gt;addAction(exportAction);
<a name="l00579"></a>00579         fileMenu-&gt;addAction(saveAsAction);
<a name="l00580"></a>00580         fileMenu-&gt;addAction(openAction);
<a name="l00581"></a>00581     fileMenu-&gt;addAction(exitAction);
<a name="l00582"></a>00582 
<a name="l00583"></a>00583     editMenu = menuBar()-&gt;addMenu(tr(<span class="stringliteral">&quot;&amp;Edit&quot;</span>));
<a name="l00584"></a>00584     editMenu-&gt;addAction(addALinkAction);
<a name="l00585"></a>00585     editMenu-&gt;addAction(addSLinkAction);
<a name="l00586"></a>00586     editMenu-&gt;addAction(addQLinkAction);
<a name="l00587"></a>00587 
<a name="l00588"></a>00588     editMenu-&gt;addSeparator();
<a name="l00589"></a>00589     editMenu-&gt;addAction(joinAction);
<a name="l00590"></a>00590     editMenu-&gt;addAction(deleteAction);
<a name="l00591"></a>00591     editMenu-&gt;addSeparator();
<a name="l00592"></a>00592     editMenu-&gt;addAction(bringToFrontAction);
<a name="l00593"></a>00593     editMenu-&gt;addAction(sendToBackAction);
<a name="l00594"></a>00594     editMenu-&gt;addSeparator();
<a name="l00595"></a>00595     editMenu-&gt;addAction(propertiesAction);
<a name="l00596"></a>00596 
<a name="l00597"></a>00597 
<a name="l00598"></a>00598         <span class="comment">// generamos el insert menu a partir de la lista que nos devuelve el controlador</span>
<a name="l00599"></a>00599         insertMenu = menuBar()-&gt;addMenu(tr(<span class="stringliteral">&quot;&amp;Insert&quot;</span>));
<a name="l00600"></a>00600 
<a name="l00601"></a>00601         QMap&lt;QString, QList&lt;QString&gt; &gt; itemTypes = designer-&gt;getItemTypes();
<a name="l00602"></a>00602         <span class="keywordflow">foreach</span> (QString group, itemTypes.keys()) {
<a name="l00603"></a>00603                 QMenu *submenu = insertMenu-&gt;addMenu(group);
<a name="l00604"></a>00604                 submenu-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00605"></a>00605                 insertSubmenus.append(submenu);
<a name="l00606"></a>00606 
<a name="l00607"></a>00607                 <span class="keywordflow">foreach</span> (QString item, itemTypes.value(group))
<a name="l00608"></a>00608                 {
<a name="l00609"></a>00609                         InsertAction *action = <span class="keyword">new</span> InsertAction(item, <span class="keyword">this</span>);
<a name="l00610"></a>00610                         action-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00611"></a>00611                         connect(action, SIGNAL(triggered(QString)), <span class="keyword">this</span>, SLOT(insertItem(QString)));
<a name="l00612"></a>00612                         submenu-&gt;addAction(action);
<a name="l00613"></a>00613                 }
<a name="l00614"></a>00614         }
<a name="l00615"></a>00615         insertUserSubmenu = insertMenu-&gt;addMenu(<span class="stringliteral">&quot;User node&quot;</span>);
<a name="l00616"></a>00616         insertUserSubmenu-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00617"></a>00617         insertSubmenus.append(insertUserSubmenu);
<a name="l00618"></a>00618 }
<a name="l00619"></a>00619 
<a name="l00620"></a>00620 <span class="keywordtype">void</span> SlateWindow::includeItemType(QString itemType)
<a name="l00621"></a>00621 {
<a name="l00622"></a>00622         InsertAction *action = <span class="keyword">new</span> InsertAction(itemType, <span class="keyword">this</span>);
<a name="l00623"></a>00623         action-&gt;setEnabled(<span class="keyword">false</span>);
<a name="l00624"></a>00624         connect(action, SIGNAL(triggered(QString)), <span class="keyword">this</span>, SLOT(insertItem(QString)));
<a name="l00625"></a>00625         insertUserSubmenu-&gt;addAction(action);
<a name="l00626"></a>00626 
<a name="l00627"></a>00627         updateActions();
<a name="l00628"></a>00628 }
<a name="l00629"></a>00629 
<a name="l00630"></a>00630 <span class="keywordtype">void</span> SlateWindow::createToolBars()
<a name="l00631"></a>00631 {
<a name="l00632"></a>00632     editToolBar = addToolBar(tr(<span class="stringliteral">&quot;Edit&quot;</span>));
<a name="l00633"></a>00633     editToolBar-&gt;addAction(addALinkAction);
<a name="l00634"></a>00634     editToolBar-&gt;addAction(addSLinkAction);
<a name="l00635"></a>00635     editToolBar-&gt;addAction(addQLinkAction);
<a name="l00636"></a>00636     editToolBar-&gt;addAction(joinAction);
<a name="l00637"></a>00637     editToolBar-&gt;addAction(deleteAction);
<a name="l00638"></a>00638     editToolBar-&gt;addSeparator();
<a name="l00639"></a>00639     editToolBar-&gt;addSeparator();
<a name="l00640"></a>00640     editToolBar-&gt;addAction(bringToFrontAction);
<a name="l00641"></a>00641     editToolBar-&gt;addAction(sendToBackAction);
<a name="l00642"></a>00642 
<a name="l00643"></a>00643         editToolBar-&gt;addSeparator();
<a name="l00644"></a>00644         editToolBar-&gt;addAction(runAction);
<a name="l00645"></a>00645         editToolBar-&gt;addAction(stopAction);
<a name="l00646"></a>00646 }
<a name="l00647"></a>00647 
<a name="l00648"></a>00648 Node *SlateWindow::selectedNode()<span class="keyword"> const</span>
<a name="l00649"></a>00649 <span class="keyword"></span>{
<a name="l00650"></a>00650     QList&lt;QGraphicsItem *&gt; items = scene-&gt;selectedItems();
<a name="l00651"></a>00651     <span class="keywordflow">if</span> (items.count() == 1) {
<a name="l00652"></a>00652         <span class="keywordflow">return</span> <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(items.first());
<a name="l00653"></a>00653     } <span class="keywordflow">else</span> {
<a name="l00654"></a>00654         <span class="keywordflow">return</span> 0;
<a name="l00655"></a>00655     }
<a name="l00656"></a>00656 }
<a name="l00657"></a>00657 
<a name="l00658"></a>00658 Link *SlateWindow::selectedLink()<span class="keyword"> const</span>
<a name="l00659"></a>00659 <span class="keyword"></span>{
<a name="l00660"></a>00660     QList&lt;QGraphicsItem *&gt; items = scene-&gt;selectedItems();
<a name="l00661"></a>00661     <span class="keywordflow">if</span> (items.count() == 1) {
<a name="l00662"></a>00662         <span class="keywordflow">return</span> <span class="keyword">dynamic_cast&lt;</span>Link *<span class="keyword">&gt;</span>(items.first());
<a name="l00663"></a>00663     } <span class="keywordflow">else</span> {
<a name="l00664"></a>00664         <span class="keywordflow">return</span> 0;
<a name="l00665"></a>00665     }
<a name="l00666"></a>00666 }
<a name="l00667"></a>00667 
<a name="l00668"></a>00668 SlateWindow::NodePair SlateWindow::selectedNodePair()<span class="keyword"> const</span>
<a name="l00669"></a>00669 <span class="keyword"></span>{
<a name="l00670"></a>00670     QList&lt;QGraphicsItem *&gt; items = scene-&gt;selectedItems();
<a name="l00671"></a>00671     <span class="keywordflow">if</span> (items.count() == 2) {
<a name="l00672"></a>00672         Node *first = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(items.first());
<a name="l00673"></a>00673         Node *second = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(items.last());
<a name="l00674"></a>00674         <span class="keywordflow">if</span> (first &amp;&amp; second)
<a name="l00675"></a>00675             <span class="keywordflow">return</span> NodePair(first, second);
<a name="l00676"></a>00676     }
<a name="l00677"></a>00677     <span class="keywordflow">return</span> NodePair();
<a name="l00678"></a>00678 }
<a name="l00679"></a>00679 
<a name="l00680"></a>00680 <span class="comment">// devuelve la lista de onlyParents seleccionados, si todos ellos comparten padre (ya sea 0 o un grupo), tambien devuelve los link de dicha lista</span>
<a name="l00681"></a>00681 QList&lt;QGraphicsItem *&gt; SlateWindow::selectedNodeGroup()<span class="keyword"> const</span>
<a name="l00682"></a>00682 <span class="keyword"></span>{
<a name="l00683"></a>00683     QList&lt;QGraphicsItem *&gt; items = onlyParents(scene-&gt;selectedItems());
<a name="l00684"></a>00684 
<a name="l00685"></a>00685         <span class="comment">//si quedan almemos dos</span>
<a name="l00686"></a>00686     <span class="keywordflow">if</span> (items.count() &gt; 1) {
<a name="l00687"></a>00687                 <span class="comment">// y si comparten padre</span>
<a name="l00688"></a>00688                 QGraphicsItem * parent = 0;
<a name="l00689"></a>00689                 QMutableListIterator&lt;QGraphicsItem *&gt; i(items);
<a name="l00690"></a>00690                 <span class="keywordflow">if</span> (i.hasNext()) parent = i.next()-&gt;parentItem();
<a name="l00691"></a>00691 
<a name="l00692"></a>00692                 <span class="keywordflow">while</span> (i.hasNext())
<a name="l00693"></a>00693                         <span class="keywordflow">if</span> ( i.next()-&gt;parentItem() != parent) <span class="keywordflow">return</span> QList&lt;QGraphicsItem *&gt;();
<a name="l00694"></a>00694 
<a name="l00695"></a>00695                 <span class="keywordflow">return</span> items;
<a name="l00696"></a>00696     }
<a name="l00697"></a>00697     <span class="keywordflow">return</span> items;
<a name="l00698"></a>00698 }
<a name="l00699"></a>00699 
<a name="l00700"></a>00700 <span class="comment">// obtiene los QGraphicsItem de la lista cuyo padre no pertenece a la lista</span>
<a name="l00701"></a>00701 QList&lt;QGraphicsItem *&gt; SlateWindow::onlyParents(QList&lt;QGraphicsItem *&gt; items)<span class="keyword"> const</span>
<a name="l00702"></a>00702 <span class="keyword"></span>{
<a name="l00703"></a>00703     QList&lt;QGraphicsItem *&gt; parentItems;
<a name="l00704"></a>00704 
<a name="l00705"></a>00705     QMutableListIterator&lt;QGraphicsItem *&gt; i(items);
<a name="l00706"></a>00706     <span class="keywordflow">while</span> (i.hasNext()) {
<a name="l00707"></a>00707                 i.next();
<a name="l00708"></a>00708                 <span class="keywordtype">bool</span> parent = <span class="keyword">true</span>;
<a name="l00709"></a>00709                 QMutableListIterator&lt;QGraphicsItem *&gt; j(items);
<a name="l00710"></a>00710                 <span class="keywordflow">while</span> (j.hasNext()) {
<a name="l00711"></a>00711                         j.next();
<a name="l00712"></a>00712                         <span class="keywordflow">if</span> ( (i.value()) &amp;&amp; (i.value()-&gt;parentItem() == j.value()) ) {
<a name="l00713"></a>00713                                 parent = <span class="keyword">false</span>;
<a name="l00714"></a>00714                                 <span class="keywordflow">break</span>;
<a name="l00715"></a>00715                         }
<a name="l00716"></a>00716                 }
<a name="l00717"></a>00717                 <span class="keywordflow">if</span> (parent) parentItems.append(i.value());
<a name="l00718"></a>00718     }
<a name="l00719"></a>00719 
<a name="l00720"></a>00720         <span class="keywordflow">return</span> parentItems;
<a name="l00721"></a>00721 }
<a name="l00722"></a>00722 
<a name="l00723"></a>00723 <span class="keywordtype">bool</span> SlateWindow::exportAs()
<a name="l00724"></a>00724 {
<a name="l00725"></a>00725     QString fileName = QFileDialog::getSaveFileName(<span class="keyword">this</span>,
<a name="l00726"></a>00726                                tr(<span class="stringliteral">&quot;Save C++&quot;</span>), <span class="stringliteral">&quot;.&quot;</span>,
<a name="l00727"></a>00727                                tr(<span class="stringliteral">&quot;C++ files (*.cpp)&quot;</span>));
<a name="l00728"></a>00728     <span class="keywordflow">if</span> (fileName.isEmpty())
<a name="l00729"></a>00729         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00730"></a>00730         <span class="keywordflow">return</span> saveFile(fileName, <span class="keyword">false</span>);
<a name="l00731"></a>00731 }
<a name="l00732"></a>00732 
<a name="l00733"></a>00733 <span class="keywordtype">bool</span> SlateWindow::saveAs()
<a name="l00734"></a>00734 {
<a name="l00735"></a>00735     QString fileName = QFileDialog::getSaveFileName(<span class="keyword">this</span>,
<a name="l00736"></a>00736                                tr(<span class="stringliteral">&quot;Save XML&quot;</span>), <span class="stringliteral">&quot;.&quot;</span>,
<a name="l00737"></a>00737                                tr(<span class="stringliteral">&quot;XML files (*.xml)&quot;</span>));
<a name="l00738"></a>00738     <span class="keywordflow">if</span> (fileName.isEmpty())
<a name="l00739"></a>00739         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00740"></a>00740         <span class="keywordflow">return</span> saveFile(fileName, <span class="keyword">true</span>);
<a name="l00741"></a>00741 }
<a name="l00742"></a>00742 
<a name="l00743"></a>00743 <span class="keywordtype">bool</span> SlateWindow::open()
<a name="l00744"></a>00744 {
<a name="l00745"></a>00745     QString fileName = QFileDialog::getOpenFileName(<span class="keyword">this</span>,
<a name="l00746"></a>00746                                tr(<span class="stringliteral">&quot;Open File&quot;</span>), <span class="stringliteral">&quot;.&quot;</span>,
<a name="l00747"></a>00747                                tr(<span class="stringliteral">&quot;XML files (*.xml)&quot;</span>));
<a name="l00748"></a>00748     <span class="keywordflow">if</span> (fileName.isEmpty()) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00749"></a>00749 
<a name="l00750"></a>00750 
<a name="l00751"></a>00751     QFile file(fileName);
<a name="l00752"></a>00752     <span class="keywordflow">if</span> (!file.open(QIODevice::ReadOnly)) {
<a name="l00753"></a>00753         QMessageBox::warning(<span class="keyword">this</span>, tr(<span class="stringliteral">&quot;QVDesignerGUI&quot;</span>),
<a name="l00754"></a>00754                              tr(<span class="stringliteral">&quot;Cannot open file %1:\n%2.&quot;</span>)
<a name="l00755"></a>00755                              .arg(file.fileName())
<a name="l00756"></a>00756                              .arg(file.errorString()));
<a name="l00757"></a>00757         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00758"></a>00758     }
<a name="l00759"></a>00759         QTextStream in(&amp;file);
<a name="l00760"></a>00760     <span class="keywordflow">return</span> (designer-&gt;loadXML(in.readAll()));
<a name="l00761"></a>00761 }
<a name="l00762"></a>00762 
<a name="l00763"></a>00763 <span class="keywordtype">bool</span> SlateWindow::saveFile(<span class="keyword">const</span> QString &amp;fileName, <span class="keywordtype">bool</span> xmlFile)
<a name="l00764"></a>00764 {
<a name="l00765"></a>00765     QFile file(fileName);
<a name="l00766"></a>00766     <span class="keywordflow">if</span> (!file.open(QIODevice::WriteOnly)) {
<a name="l00767"></a>00767         QMessageBox::warning(<span class="keyword">this</span>, tr(<span class="stringliteral">&quot;QVDesignerGUI&quot;</span>),
<a name="l00768"></a>00768                              tr(<span class="stringliteral">&quot;Cannot write file %1:\n%2.&quot;</span>)
<a name="l00769"></a>00769                              .arg(file.fileName())
<a name="l00770"></a>00770                              .arg(file.errorString()));
<a name="l00771"></a>00771         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00772"></a>00772     }
<a name="l00773"></a>00773 
<a name="l00774"></a>00774     QTextStream out(&amp;file);
<a name="l00775"></a>00775         <span class="keywordflow">if</span> (xmlFile)
<a name="l00776"></a>00776                 out &lt;&lt; designer-&gt;getXMLText();
<a name="l00777"></a>00777         <span class="keywordflow">else</span>
<a name="l00778"></a>00778             out &lt;&lt; designer-&gt;getCppText();
<a name="l00779"></a>00779 
<a name="l00780"></a>00780     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00781"></a>00781 }
<a name="l00782"></a>00782 
<a name="l00783"></a>00783 <span class="keywordtype">void</span> SlateWindow::showMessage(QString message)
<a name="l00784"></a>00784 {
<a name="l00785"></a>00785         <span class="keywordflow">if</span> (statusbar)
<a name="l00786"></a>00786                 statusbar-&gt;showMessage(message, 10000); <span class="comment">// lo muestra 10 segundos</span>
<a name="l00787"></a>00787 }
<a name="l00788"></a>00788 
<a name="l00789"></a>00789 
<a name="l00790"></a>00790 <span class="keywordtype">void</span> SlateWindow::arrangeItems()
<a name="l00791"></a>00791 {
<a name="l00792"></a>00792         QList&lt;QList&lt;Node *&gt; *&gt; levels;
<a name="l00793"></a>00793         <span class="keywordtype">int</span> left = 10;
<a name="l00794"></a>00794         <span class="keywordtype">int</span> bottom = 20;
<a name="l00795"></a>00795         <span class="keyword">const</span> <span class="keywordtype">int</span> MARGIN = 20;
<a name="l00796"></a>00796 
<a name="l00797"></a>00797         <span class="comment">// obtengo los niveles en que se encuentran los items, organizandolos por columnas en &quot;levels&quot;</span>
<a name="l00798"></a>00798         <span class="keywordflow">foreach</span>(Node *node, insertNodes) {
<a name="l00799"></a>00799                 <span class="keywordtype">int</span> level = node-&gt;precursors();
<a name="l00800"></a>00800                 <span class="keywordflow">while</span>(levels.size() &lt;= level)
<a name="l00801"></a>00801                         levels.append(<span class="keyword">new</span> QList&lt;Node *&gt;);
<a name="l00802"></a>00802                 levels[level]-&gt;append(node);
<a name="l00803"></a>00803         }
<a name="l00804"></a>00804 
<a name="l00805"></a>00805         <span class="comment">//muevo los items en la pizarra en función de los tamaños y niveles de estos</span>
<a name="l00806"></a>00806         <span class="keywordflow">foreach</span>(QList&lt;Node *&gt; *levelNodes, levels) {
<a name="l00807"></a>00807                 <span class="keywordtype">int</span> maxWidth = 0;
<a name="l00808"></a>00808                 <span class="keywordflow">if</span> (levelNodes) {
<a name="l00809"></a>00809                         <span class="keywordflow">foreach</span>(Node *node, *levelNodes) {
<a name="l00810"></a>00810                                 node-&gt;setPos(QPoint(left, bottom));
<a name="l00811"></a>00811                                 insertNodesPos.insert(insertNodes.key(node), node-&gt;pos());
<a name="l00812"></a>00812                                 bottom += (int)node-&gt;boundingRect().height() + MARGIN; <span class="comment">//le sumo a bottom el alto mas un margen</span>
<a name="l00813"></a>00813                                 <span class="keywordtype">int</span> width = (int)node-&gt;boundingRect().width();
<a name="l00814"></a>00814                                 <span class="keywordflow">if</span> (maxWidth &lt; width) maxWidth = width; <span class="comment">//actualiza maxWidth</span>
<a name="l00815"></a>00815                         }
<a name="l00816"></a>00816                 }
<a name="l00817"></a>00817                 left += maxWidth + MARGIN; <span class="comment">//le sumo a left maxWide mas un margen</span>
<a name="l00818"></a>00818                 bottom = 20;<span class="comment">//reseteo bottom</span>
<a name="l00819"></a>00819         }
<a name="l00820"></a>00820 
<a name="l00821"></a>00821         <span class="comment">// vacio la estructura usada</span>
<a name="l00822"></a>00822         <span class="keywordflow">foreach</span>(QList&lt;Node *&gt; *levelNodes, levels) {
<a name="l00823"></a>00823                 levelNodes-&gt;clear();
<a name="l00824"></a>00824                 <span class="keyword">delete</span> levelNodes;
<a name="l00825"></a>00825         }
<a name="l00826"></a>00826 }
<a name="l00827"></a>00827 
<a name="l00828"></a>00828 QPointF SlateWindow::getNodePos(uint <span class="keywordtype">id</span>)<span class="keyword"> const</span>
<a name="l00829"></a>00829 <span class="keyword"></span>{
<a name="l00830"></a>00830         <span class="keywordflow">return</span> insertNodes.value(<span class="keywordtype">id</span>)-&gt;pos();
<a name="l00831"></a>00831 }
<a name="l00832"></a>00832 
<a name="l00833"></a>00833 <span class="keywordtype">bool</span> SlateWindow::moveNode(uint <span class="keywordtype">id</span>, QPointF pos)
<a name="l00834"></a>00834 {
<a name="l00835"></a>00835         <span class="keywordflow">if</span> (insertNodes.contains(<span class="keywordtype">id</span>)) {
<a name="l00836"></a>00836                 Node *node = insertNodes.value(<span class="keywordtype">id</span>);
<a name="l00837"></a>00837                 node-&gt;setPos(pos);
<a name="l00838"></a>00838                 insertNodesPos.remove(<span class="keywordtype">id</span>);
<a name="l00839"></a>00839                 insertNodesPos.insert(<span class="keywordtype">id</span>, node-&gt;pos());
<a name="l00840"></a>00840                 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00841"></a>00841         }
<a name="l00842"></a>00842 
<a name="l00843"></a>00843         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00844"></a>00844 }
<a name="l00845"></a>00845 
<a name="l00846"></a>00846 QList&lt;GroupInfo&gt; SlateWindow::getGroups()
<a name="l00847"></a>00847 {
<a name="l00848"></a>00848         <span class="comment">// actualizo las posiciones de los grupos antes de pasarlos</span>
<a name="l00849"></a>00849         <span class="keywordflow">foreach</span>(Node *group, createdGroupInfos.keys()) {
<a name="l00850"></a>00850                 createdGroupInfos[group].setPos(group-&gt;pos());
<a name="l00851"></a>00851                 createdGroupInfos[group].setName(group-&gt;getName());
<a name="l00852"></a>00852                 <span class="keywordflow">if</span> (dynamic_cast&lt;GroupNode *&gt;(group))
<a name="l00853"></a>00853                         createdGroupInfos[group].setAbstract( ((GroupNode *)group)-&gt;getAbstract() );
<a name="l00854"></a>00854         }
<a name="l00855"></a>00855 
<a name="l00856"></a>00856         <span class="keywordflow">return</span> createdGroupInfos.values();
<a name="l00857"></a>00857 }
<a name="l00858"></a>00858 
<a name="l00859"></a>00859 <span class="keywordtype">void</span> SlateWindow::eraseGroups()
<a name="l00860"></a>00860 {
<a name="l00861"></a>00861         <span class="keywordflow">foreach</span>(Node *group, createdGroupInfos.keys()) {
<a name="l00862"></a>00862                 <span class="keyword">delete</span> group;
<a name="l00863"></a>00863         }
<a name="l00864"></a>00864 
<a name="l00865"></a>00865         createdGroupInfos.clear();
<a name="l00866"></a>00866         createdGroups.clear();
<a name="l00867"></a>00867 }
<a name="l00868"></a>00868 
<a name="l00869"></a>00869 uint SlateWindow::createGroup(GroupInfo info)
<a name="l00870"></a>00870 {
<a name="l00871"></a>00871         QList&lt;QGraphicsItem *&gt; group;
<a name="l00872"></a>00872         <span class="keywordflow">foreach</span> (uint nodeId, info.getNodes()) {
<a name="l00873"></a>00873                 <span class="keywordflow">if</span> (insertNodes.contains(nodeId)) {
<a name="l00874"></a>00874                         group.append(insertNodes.value(nodeId));
<a name="l00875"></a>00875                 }
<a name="l00876"></a>00876                 <span class="keywordflow">else</span> {
<a name="l00877"></a>00877 <span class="comment">//                      std::cout &lt;&lt; QString(&quot;ERROR: Devuelvo 0 porque no existe el nodo %1\n&quot;).arg(nodeId).toStdString();</span>
<a name="l00878"></a>00878                         <span class="keywordflow">return</span> 0;
<a name="l00879"></a>00879                 }
<a name="l00880"></a>00880         }
<a name="l00881"></a>00881         <span class="keywordflow">foreach</span> (uint subgroupId, info.getSubgroups()) {
<a name="l00882"></a>00882                 <span class="keywordflow">if</span> (createdGroups.contains(subgroupId)) {
<a name="l00883"></a>00883                         group.append(createdGroups.value(subgroupId));
<a name="l00884"></a>00884                 }
<a name="l00885"></a>00885                 <span class="keywordflow">else</span> {
<a name="l00886"></a>00886 <span class="comment">//                      std::cout &lt;&lt; QString(&quot;ERROR: Devuelvo 0 porque no existe el grupo %1\n&quot;).arg(subgroupId).toStdString();</span>
<a name="l00887"></a>00887                         <span class="keywordflow">return</span> 0;
<a name="l00888"></a>00888                 }
<a name="l00889"></a>00889         }
<a name="l00890"></a>00890 
<a name="l00891"></a>00891         <span class="comment">// creo el nuevo grupo</span>
<a name="l00892"></a>00892     GroupNode *node = <span class="keyword">new</span> GroupNode(info.getName(), <span class="keyword">this</span>, 0, scene);
<a name="l00893"></a>00893         node-&gt;setPos(info.getPos());
<a name="l00894"></a>00894 
<a name="l00895"></a>00895         <span class="comment">// si los items seleccionados estaban ya dentro de otro grupo, este se añade a el (sino a la escena)</span>
<a name="l00896"></a>00896         <span class="keywordflow">if</span> ( !group.isEmpty() &amp;&amp; group.first() &amp;&amp; group.first()-&gt;parentItem() ) {
<a name="l00897"></a>00897                 GroupNode *parentNode = <span class="keyword">dynamic_cast&lt;</span>GroupNode *<span class="keyword">&gt;</span>(group.first()-&gt;parentItem());
<a name="l00898"></a>00898                 <span class="keywordflow">if</span> (parentNode) parentNode-&gt;addNode(node);
<a name="l00899"></a>00899         }
<a name="l00900"></a>00900 
<a name="l00901"></a>00901         <span class="comment">// para cada item si es un nodo lo añado al nuevo grupo</span>
<a name="l00902"></a>00902         <span class="keywordflow">foreach</span> (QGraphicsItem *item, group) {
<a name="l00903"></a>00903                 Node *itemNode = <span class="keyword">dynamic_cast&lt;</span>Node *<span class="keyword">&gt;</span>(item);
<a name="l00904"></a>00904                 <span class="keywordflow">if</span> (itemNode) {
<a name="l00905"></a>00905                         node-&gt;addNode(itemNode);
<a name="l00906"></a>00906 
<a name="l00907"></a>00907                         <span class="comment">//se actualiza el tamaño de sus links</span>
<a name="l00908"></a>00908                         <span class="comment">//y si la otra punta no se va a meter al grupo pasa a formar parte de este</span>
<a name="l00909"></a>00909                         <span class="keywordflow">foreach</span> (Link *link, itemNode-&gt;getInLinks()) {
<a name="l00910"></a>00910                                 Node *other = link-&gt;fromNode();
<a name="l00911"></a>00911                                 <span class="keywordflow">if</span> (group.contains(other)) {
<a name="l00912"></a>00912                                         QPen pen = link-&gt;pen();
<a name="l00913"></a>00913                                         pen.setWidthF(pen.width()*0.5);
<a name="l00914"></a>00914                                         link-&gt;setPen(pen);
<a name="l00915"></a>00915                                         link-&gt;update();
<a name="l00916"></a>00916                                 }
<a name="l00917"></a>00917                         }
<a name="l00918"></a>00918                         <span class="keywordflow">foreach</span> (Link *link, itemNode-&gt;getOutLinks()) {
<a name="l00919"></a>00919                                 Node *other = link-&gt;toNode();
<a name="l00920"></a>00920                                 <span class="keywordflow">if</span> (group.contains(other)) {
<a name="l00921"></a>00921                                         QPen pen = link-&gt;pen();
<a name="l00922"></a>00922                                         pen.setWidthF(pen.width()*0.5);
<a name="l00923"></a>00923                                         link-&gt;setPen(pen);
<a name="l00924"></a>00924                                         link-&gt;update();
<a name="l00925"></a>00925                                 }
<a name="l00926"></a>00926                         }
<a name="l00927"></a>00927                         itemNode-&gt;updateLinksPos(); <span class="comment">// para que se actualiza la posición y tamaño de los links del nodo</span>
<a name="l00928"></a>00928                 }
<a name="l00929"></a>00929         }
<a name="l00930"></a>00930 
<a name="l00931"></a>00931         createdGroupInfos.insert(node, node-&gt;getInfo());
<a name="l00932"></a>00932         createdGroups.insert(node-&gt;getId(), node);
<a name="l00933"></a>00933         node-&gt;abstractView(info.getAbstract());
<a name="l00934"></a>00934 
<a name="l00935"></a>00935         <span class="keywordflow">return</span> node-&gt;getId();
<a name="l00936"></a>00936 }
<a name="l00937"></a>00937 
<a name="l00938"></a>00938 
<a name="l00939"></a>00939 
</pre></div></div>
</td></tr></table>

<br /><hr><br />
<center><a href="http://perception.inf.um.es/QVision">QVision framework</a>.
<a href="http://perception.inf.um.es">PARP research group</a>.
Copyright &copy; 2007, 2008, 2009, 2010, 2011.</center>
<br />
</body>
</html>
